package la.iok.hzsvn.lewin.movie.services;

import la.iok.hzsvn.lewin.movie.core.model.*;
import la.iok.hzsvn.lewin.movie.core.movieservice.vo.MovieLevelVo;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.annotations.NotNullElement;
import la.iok.hzsvn.share.annotations.Nullable;
import la.iok.hzsvn.share.response.ListDataResponse;
import la.iok.hzsvn.share.response.SingleDataResponse;
import org.springframework.core.ParameterizedTypeReference;

import java.util.Collection;
import java.util.List;

public interface MovieServiceInvoker {
    ParameterizedTypeReference<SingleDataResponse<SimpleOrgUnitVo>> ORG_UNIT_RES_TYPE =
            new ParameterizedTypeReference<SingleDataResponse<SimpleOrgUnitVo>>() {};
    ParameterizedTypeReference<ListDataResponse<SimpleOrgUnitVo>> ORG_UNIT_LIST_RES_TYPE =
            new ParameterizedTypeReference<ListDataResponse<SimpleOrgUnitVo>>() {};
    ParameterizedTypeReference<SingleDataResponse<RoomVo>> ROOM_TYPE =
            new ParameterizedTypeReference<SingleDataResponse<RoomVo>>() {};
    ParameterizedTypeReference<ListDataResponse<RoomVo>> ROOM_RES_TYPE =
            new ParameterizedTypeReference<ListDataResponse<RoomVo>>() {};
    ParameterizedTypeReference<ListDataResponse<Long>> LIST_LONG_RES_TYPE =
            new ParameterizedTypeReference<ListDataResponse<Long>>() {};
    ParameterizedTypeReference<SingleDataResponse<DeviceVo>> DEVICE_RES_TYPE =
            new ParameterizedTypeReference<SingleDataResponse<DeviceVo>>() {};
    ParameterizedTypeReference<SingleDataResponse<UserVo>> USER_RES_TYPE =
            new ParameterizedTypeReference<SingleDataResponse<UserVo>>() {};
    ParameterizedTypeReference<ListDataResponse<SimpleUser>> USER_LIST_RES_TYPE =
            new ParameterizedTypeReference<ListDataResponse<SimpleUser>>() {};
    ParameterizedTypeReference<SingleDataResponse<MovieVo>> MOVIE_RES_TYPE =
            new ParameterizedTypeReference<SingleDataResponse<MovieVo>>() {};
    ParameterizedTypeReference<ListDataResponse<MovieVo>> MOVIE_LIST_RES_TYPE =
            new ParameterizedTypeReference<ListDataResponse<MovieVo>>() {};
    ParameterizedTypeReference<ListDataResponse<FinancialAccountVo>> LIST_ACCOUNT_RES_TYPE =
            new ParameterizedTypeReference<ListDataResponse<FinancialAccountVo>>() {};
    ParameterizedTypeReference<SingleDataResponse<PlayRecordVo>> PLAY_RECORD_RES_TYPE =
            new ParameterizedTypeReference<SingleDataResponse<PlayRecordVo>>() {};
    ParameterizedTypeReference<ListDataResponse<PlayRecordVo>> PLAY_RECORD_LIST_RES_TYPE =
            new ParameterizedTypeReference<ListDataResponse<PlayRecordVo>>() {};
    ParameterizedTypeReference<SingleDataResponse<PlayRoleInstVo>> PLAY_ROLE_INST_TYPE =
            new ParameterizedTypeReference<SingleDataResponse<PlayRoleInstVo>>() {};
    ParameterizedTypeReference<ListDataResponse<UserRoleDetail>> USER_ROLE_RES_TYPE =
            new ParameterizedTypeReference<ListDataResponse<UserRoleDetail>>() {};
    ParameterizedTypeReference<ListDataResponse<MovieLevelVo>> MOVIE_LEVEL_RES_TYPE =
            new ParameterizedTypeReference<ListDataResponse<MovieLevelVo>>() {};

    @Nullable
    RoomVo roomInfo(@Nullable Long id);

    /**
     * 查询多个房间信息
     * @param ids 房间集合
     * @return 房间列表
     */
    @NotNull
    @NotNullElement
    List<RoomVo> roomInfos(@Nullable Collection<Long> ids);

    /**
     * 查询店铺的房间列表
     * @param shopIds 店铺id列表
     * @return 房间列表
     */
    @NotNull
    @NotNullElement
    List<RoomVo> shopRooms(@Nullable Collection<Long> shopIds);

    @Nullable
    DeviceVo deviceInfo(@Nullable Long id);

    @Nullable
    DeviceVo deviceInfo(@Nullable String deviceCode);

    @Nullable
    UserVo userInfo(@Nullable Long id);

    @NotNull
    @NotNullElement
    List<SimpleUser> userInfo(@Nullable Collection<Long> ids);

    @Nullable
    MovieVo movieInfo(@Nullable Long movieId,@Nullable String version);

    /**
     * 查询剧本的最新版本实例信息
     * @since 1.1.1
     */
    @NotNull
    @NotNullElement
    List<MovieVo> latestVersions(@Nullable Collection<Long> movieIds);

    /**
     * 查询组织信息。只包含组织表本身的信息
     * @param orgUnitId 组织id
     * @return 组织信息
     */
    @Nullable
    SimpleOrgUnitVo orgUnitInfo(@Nullable Long orgUnitId);

    /**
     * 查询组织列表
     * @param orgUnitIds 组织id集合
     * @return
     */
    @NotNull
    @NotNullElement
    List<SimpleOrgUnitVo> orgUnits(@Nullable Collection<Long> orgUnitIds);
    @NotNull
    @NotNullElement
    List<Long> childrenOrgUnitIds(@Nullable Long orgUnitId);

    @NotNull
    @NotNullElement
    List<Long> childrenOrgUnitIds(@Nullable Collection<Long> orgUnitIds);

    @NotNull
    @NotNullElement
    List<FinancialAccountVo> roomAccounts(@Nullable Collection<Long> roomIds);

    /**
     * 单个房间请求
     * @param roomId 房间id
     * @return 账号余额
     */
    @Nullable
    FinancialAccountVo roomAccount(@Nullable Long roomId);

    /**
     * 查询开本记录
     * @param id 开本记录id
     * @return 开本记录
     */
    @Nullable
    PlayRecordVo playRecord(@Nullable Long id);

    /**
     * 房间中正在进行中的或者正在结束中的开本记录
     * @param roomId 房间id
     * @return 开本记录列表
     */
    @NotNull
    @NotNullElement
    List<PlayRecordVo> roomPlayingRecords(@Nullable Long roomId);

    /**
     * 查询角色实例对象
     * @param movieId 剧本id,非剧本实例id
     * @param version 剧本版本
     * @param playRoleId 角色id,非角色实例id
     * @return 角色实例
     */
    @Nullable
    PlayRoleInstVo playRoleInst(@Nullable Long movieId,@Nullable String version,@Nullable Long playRoleId);

    /**
     * 播放次数增加1
     * @param movieId 剧本id
     * @param version 版本版本
     */
    void increasePlayTimes(@NotNull Long movieId, @NotNull String version);

    /**
     * 查找用户所有的组织权限
     * @param userId 用户id
     * @return 用户组织权限列表
     */
    List<UserRoleDetail> userRoles(@Nullable Long userId);

    /**
     * 查询不支持返利的剧本id
     * @return 不支持返利的剧本id列表。是剧本id,不是剧本实例id
     */
    List<Long> unsupportedReturnMoneyMovieIds();

    /**
     * 查询剧本级别列表。此方法返回系统所有剧本级别（一般不多）
     * @return 剧本级别列表
     */
    List<MovieLevelVo> movieLevels();
}
